win32线程已退出 返回值为0 您所在的位置:网站首页 线程win32线程已退出 返回值为0怎么解决 win32线程已退出 返回值为0

win32线程已退出 返回值为0

2023-08-05 00:48| 来源: 网络整理| 查看: 265

在多线程程序中,经常要用全局变量来实现多个函数间的数据共享。由于数据空间是共享的,因此全局变量也为所有线程共有。

测试代码如下:

#include #include #include #include int key = 100; //全局变量 void *helloworld_one(void *arg) { printf("the message is %sn",(char *)arg); key = 10; printf("key=%d, the child id is %lun", key, pthread_self()); return NULL; } void *helloworld_two(void *arg) { printf("the message is %sn", (char *)arg); sleep(1); printf("key=%d, the child id is %lun", key, pthread_self()); return NULL; } int main(int argc, char *argv[]) { pthread_t thread_id_one; pthread_t thread_id_two; //创建线程 pthread_create(&thread_id_one, NULL, helloworld_one, "helloworld_one"); pthread_create(&thread_id_two, NULL, helloworld_two, "helloworld_two"); //等待线程结束,回收资源 pthread_join(thread_id_one, NULL); pthread_join(thread_id_two, NULL); return 0; }

运行结果如下:

06fdf7666ba74a1881559f2df5b5adfc.png

由运行结果可以看出,其中一个线程对全局变量的修改将影响到另一个线程的访问。

但有时应用程序设计中必要提供线程私有的全局变量,这个变量仅在线程中有效,但却可以跨过多个函数访问。比如在程序里可能需要每个线程维护一个链表,而会使用相同的函数来操作这个链表,最简单的方法就是使用同名而不同变量地址的线程相关数据结构。这样的数据结构可以由 Posix 线程库维护,成为线程私有数据 (Thread-specific Data,或称为 TSD)。

需要C/C++ Linux服务器架构师学习资料加qun获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

下面接口所需头文件:

#include

1)创建线程私有数据

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));

功能:

创建一个类型为 pthread_key_t 类型的私有数据变量( key )。

参数:

key:在分配( malloc )线程私有数据之前,需要创建和线程私有数据相关联的键( key ),这个键的功能是获得对线程私有数据的访问权。 destructor:清理函数名字( 如:fun )。当线程退出时,如果线程私有数据地址不是非 NULL,此函数会自动被调用。该函数指针可以设成 NULL ,这样系统将调用默认的清理函数。 回调函数其定义如下: void fun(void *arg) { // arg 为 key 值 }

返回值:

成功:0 失败:非 0

不论哪个线程调用 pthread_key_create(),所创建的 key 都是所有线程可访问,但各个线程可根据自己的需要往 key 中填入不同的值,相当于提供了一个同名不同值的变量。

2)注销线程私有数据

int pthread_key_delete(pthread_key_t key);

功能:

注销线程私有数据。这个函数并不会检查当前是否有线程正使用线程私有数据( key ),也不会调用清理函数 destructor() ,而只是将线程私有数据( key )释放以供下一次调用 pthread_key_create() 使用。

参数:

key:待注销的私有数据。

返回值:

成功:0 失败:非 0

3)设置线程私有数据的关联

int pthread_setspecific(pthread_key_t key, const void *value);

功能:

设置线程私有数据( key ) 和 value 关联,注意,是 value 的值(不是所指的内容)和 key 相关联。

参数:

key:线程私有数据。 value:和 key 相关联的指针。

返回值:

成功:0 失败:非 0

4)读取线程私有数据所关联的值

void *pthread_getspecific(pthread_key_t key);

功能:

读取线程私有数据( key )所关联的值。

参数:

key:线程私有数据。

返回值:

成功:线程私有数据( key )所关联的值。 失败:NULL

示例代码如下:

// this is the test code for pthread_key #include #include pthread_key_t key; // 私有数据,全局变量 void echomsg(void *t) { printf("[destructor] thread_id = %lu, param = %pn", pthread_self(), t); } void *child1(void *arg) { int i = 10; pthread_t tid = pthread_self(); //线程号 printf("nset key value %d in thread %lun", i, tid); pthread_setspecific(key, &i); // 设置私有数据 printf("thread one sleep 2 until thread two finishnn"); sleep(2); printf("nthread %lu returns %d, add is %pn", tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key) ); } void *child2(void *arg) { int temp = 20; pthread_t tid = pthread_self(); //线程号 printf("nset key value %d in thread %lun", temp, tid); pthread_setspecific(key, &temp); //设置私有数据 sleep(1); printf("thread %lu returns %d, add is %pn", tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key)); } int main(void) { pthread_t tid1,tid2; pthread_key_create(&key, echomsg); // 创建 pthread_create(&tid1, NULL, child1, NULL); pthread_create(&tid2, NULL, child2, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_key_delete(key); // 注销 return 0; }

运行结果如下:

69dd75fbc8d61ccb2ff3cba5d6adffea.png

从运行结果来看,各线程对自己的私有数据操作互不影响。也就是说,虽然 key 是同名且全局,但访问的内存空间并不是同一个。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有